#include "clienttcp.h"
//#include "ui_clienttcp.h"

// 构造函数：默认构造函数
ClientTcp::ClientTcp(QWidget *parent)
    : QMainWindow(parent), /*ui(new Ui::ClientTcp),*/ socket(new QTcpSocket(this)) {
    //    ui->setupUi(this); // 初始化 UI 组件

    // 连接信号和槽以处理 TCP 连接的状态变化
    connect(socket, &QTcpSocket::connected, this, &ClientTcp::onConnected);
    connect(socket, &QTcpSocket::disconnected, this, &ClientTcp::onDisconnected);
    connect(socket, &QTcpSocket::readyRead, this, &ClientTcp::onReadMsg);
}

// 带参数的构造函数，初始化主机和端口，并发送数据
ClientTcp::ClientTcp(const QString &host, qint16 port, QString& str)
    : ClientTcp() { // 调用默认构造函数
    this->host = host; // 设置主机地址
    this->port = port; // 设置端口号

    // 根据端口号连接相应的接收槽
    switch (port) {
    case USERS_DATA:
        connect(socket, &QTcpSocket::readyRead, this, &ClientTcp::recJsonFromUsers);
        break;
    case DOCTORS_DATA:
        connect(socket, &QTcpSocket::readyRead, this, &ClientTcp::recJsonFromDoctors);
        break;
    case PATIENTS_DATA:
        connect(socket, &QTcpSocket::readyRead, this, &ClientTcp::recJsonFromPatients);
        break;
    case MEDICAL_RECORDS_DATA:
        connect(socket, &QTcpSocket::readyRead, this, &ClientTcp::recJsonFromMedicalRecords);
        break;
    case APPOINTMENTS_DATA:
        connect(socket, &QTcpSocket::readyRead, this, &ClientTcp::recJsonFromAppointments);
        break;
    case APPOINTMENTS_DATA_2:
        connect(socket, &QTcpSocket::readyRead, this, &ClientTcp::recJsonFromAppointments_2);
        break;
    case MEDICAL_ADVICE_DATA:
        connect(socket, &QTcpSocket::readyRead, this, &ClientTcp::recJsonFromMedicalAdvice);
        break;
    case PRESCRIPTIONS_DATA:
        connect(socket, &QTcpSocket::readyRead, this, &ClientTcp::recJsonFromPrescriptions);
        break;
    case COMMUNICATION_DATA:
        connect(socket, &QTcpSocket::readyRead, this, &ClientTcp::recJsonFromCommunication);
        break;
    case HEALTH_ASSESSMENTS_DATA:
        connect(socket, &QTcpSocket::readyRead, this, &ClientTcp::recJsonFromHealthAssessments);
        break;
    case INSERT_DATA:
        connect(socket, &QTcpSocket::readyRead, this, &ClientTcp::onInsertData);
        break;
    case DEPARTMENTS_DATA:
        connect(socket,&QTcpSocket::readyRead,this,&ClientTcp::recJsonFromDepartments);
        break;
    default:
        qDebug() << "Unknown data type for port:" << port; // 未知数据类型
        break;
    }

    sendData = str; // 存储要发送的数据

    // 连接到服务器
    socket->connectToHost(host, port);

    // 连接成功后发送数据
    connect(socket, &QTcpSocket::connected, [=] {
        if (socket->state() != QAbstractSocket::ConnectedState) {
            socket->connectToHost(host, port);
        }
        QByteArray data = sendData.toUtf8(); // 将 QString 转换为 QByteArray
        qDebug() << "Sending data:" << data; // 打印将要发送的数据
        socket->write(data); // 发送数据
        socket->flush(); // 刷新缓冲区
    });
}


// 带参数的构造函数，仅初始化主机和端口
ClientTcp::ClientTcp(qint16 port,const QString &host)
    : ClientTcp() { // 调用默认构造函数
    this->host = host; // 设置主机地址
    this->port = port; // 设置端口号

    // 根据端口号连接相应的接收槽
    switch (port) {
    case USERS_DATA:
        connect(socket, &QTcpSocket::readyRead, this, &ClientTcp::recJsonFromUsers);
        break;
    case DOCTORS_DATA:
        connect(socket, &QTcpSocket::readyRead, this, &ClientTcp::recJsonFromDoctors);
        break;
    case PATIENTS_DATA:
        connect(socket, &QTcpSocket::readyRead, this, &ClientTcp::recJsonFromPatients);
        break;
    case MEDICAL_RECORDS_DATA:
        connect(socket, &QTcpSocket::readyRead, this, &ClientTcp::recJsonFromMedicalRecords);
        break;
    case APPOINTMENTS_DATA:
        connect(socket, &QTcpSocket::readyRead, this, &ClientTcp::recJsonFromAppointments);
        break;
    case APPOINTMENTS_DATA_2:
        connect(socket, &QTcpSocket::readyRead, this, &ClientTcp::recJsonFromAppointments_2);
        break;
    case MEDICAL_ADVICE_DATA:
        connect(socket, &QTcpSocket::readyRead, this, &ClientTcp::recJsonFromMedicalAdvice);
        break;
    case PRESCRIPTIONS_DATA:
        connect(socket, &QTcpSocket::readyRead, this, &ClientTcp::recJsonFromPrescriptions);
        break;
    case COMMUNICATION_DATA:
        connect(socket, &QTcpSocket::readyRead, this, &ClientTcp::recJsonFromCommunication);
        break;
    case HEALTH_ASSESSMENTS_DATA:
        connect(socket, &QTcpSocket::readyRead, this, &ClientTcp::recJsonFromHealthAssessments);
        break;
    case INSERT_DATA:
        connect(socket, &QTcpSocket::readyRead, this, &ClientTcp::onInsertData);
        break;
    case DEPARTMENTS_DATA:
        connect(socket,&QTcpSocket::readyRead,this,&ClientTcp::recJsonFromDepartments);
        break;
    default:
        qDebug() << "Unknown data type for port:" << port; // 未知数据类型
        break;
    }

    // 连接到服务器
    //    socket->connectToHost(host, port);
}

void ClientTcp::onInsertData() {
    if(receivedData == "Successful"){
        flag = true;
    }
    else {
        flag = false;
    }
}

ClientTcp::~ClientTcp() {
    //    delete ui; // 删除 UI 组件
    // socket 在 Qt 的父子关系中会自动删除，无需手动 delete
}

// 处理连接成功的槽函数
void ClientTcp::onConnected() {

    qDebug() << "==================================";
    qDebug() << "连接成功"; // 打印连接成功信息
    qDebug() << "==================================";
}

// 处理断开连接的槽函数
void ClientTcp::onDisconnected() {
    qDebug() << "已断开连接"; // 打印断开连接信息
    socket->close(); // 可选，socket.close() 会关闭连接
    socket = nullptr; // 将 socket 设置为 nullptr，以便在需要时重新创建
}

void ClientTcp::onReadMsg() {
    receivedData = socket->readAll(); // 读取所有可用数据
    qDebug() << "==================================";
    qDebug() << "Received data length:" << receivedData.length(); // 打印接收到的数据长度
    qDebug() << "Received data:" << receivedData; // 打印接收到的数据
    qDebug() << "==================================";
}


void ClientTcp::sendMsg(QString& str) const {
    // 检查套接字状态
    if (socket->state() == QAbstractSocket::ConnectedState) {
        // 发送数据
        QByteArray data = str.toUtf8(); // 将 QString 转换为 QByteArray
        socket->write(data); // 发送数据
        socket->flush(); // 刷新缓冲区
        qDebug() << "==================================";
        qDebug() << "Sent data:" << data; // 打印发送的数据
        qDebug() << "==================================";
    } else {
        // 如果没有连接，尝试连接
        //        qDebug() << "当前状态：" << socket->state(); // 输出当前状态
        socket->connectToHost(DEFAULT_HOST,port);
        if (!socket->waitForConnected(3000)) { // 等待连接，设置超时
            qDebug() << "Connection failed:" << socket->errorString();
            return; // 连接失败，退出函数
        }
        // 连接成功后，发送数据
        QByteArray data = str.toUtf8(); // 将 QString 转换为 QByteArray
        socket->write(data); // 发送数据
        socket->flush(); // 刷新缓冲区
        qDebug() << "Sent data after reconnect:" << data; // 打印发送的数据
    }
}

void ClientTcp::recJsonFromDepartments() {
    processJson(receivedData, {"DepartmentID", "DepartmentName", "Description"});
    // qDebug() << "Received department data";
}

// 接收用户数据的槽函数
void ClientTcp::recJsonFromUsers() {
    processJson(receivedData, {"UserID", "Username", "Password", "Role", "Name", "Gender", "Age", "ContactNumber", "Email"});
}

// 接收医生数据的槽函数
void ClientTcp::recJsonFromDoctors() {
    processJson(receivedData, {"DoctorID", "Name", "ContactNumber", "Specialization", "Experience", "Department", "Title", "Introduction", "AvatarPath","Username", "Password", "Role"});
}


// 接收患者数据的槽函数
void ClientTcp::recJsonFromPatients() {
    processJson(receivedData, {"PatientID", "MedicalHistory", "Allergies"});
}

// 接收病历数据的槽函数
void ClientTcp::recJsonFromMedicalRecords() {
    processJson(receivedData, {"RecordID", "PatientID", "DoctorID", "Diagnosis", "Treatment", "Date"});
}

// 接收预约数据的槽函数
void ClientTcp::recJsonFromAppointments() {
    // 处理从数据库中接收到的 JSON 数据
    processJson(receivedData, {"AppointmentID", "AppointmentDate", "Status", "DoctorID", "DoctorName", "Department"});
}


void ClientTcp::recJsonFromAppointments_2() {
    processJson(receivedData, {"AppointmentID", "PatientID", "DoctorID", "AppointmentDate", "Status","PatientName"});
}

// 接收医疗建议数据的槽函数
void ClientTcp::recJsonFromMedicalAdvice() {
    processJson(receivedData, {"AdviceID", "PatientID", "DoctorID", "Advice", "Date"});
}

// 接收处方数据的槽函数
void ClientTcp::recJsonFromPrescriptions() {
    processJson(receivedData, {"PrescriptionID", "PatientID", "DoctorID", "Medication", "Dosage", "Date"});
}

// 接收沟通数据的槽函数
void ClientTcp::recJsonFromCommunication() {
    processJson(receivedData, {"MessageID", "PatientID", "DoctorID", "Message", "Date"});
}

// 接收健康评估数据的槽函数
void ClientTcp::recJsonFromHealthAssessments() {
    processJson(receivedData, {"AssessmentID", "PatientID", "Assessment", "Date"});
}

// 处理 JSON 数据的通用函数
void ClientTcp::processJson(const QString &data, const QStringList &keys) {
    QJsonDocument jsonDoc = QJsonDocument::fromJson(data.toUtf8()); // 将字符串转换为 QJsonDocument
    if (jsonDoc.isArray()) { // 检查是否是 JSON 数组
        QJsonArray jsonArray = jsonDoc.array(); // 获取 JSON 数组
        for (const QJsonValue &value : jsonArray) {
            QJsonObject obj = value.toObject(); // 获取每个对象
            QJsonObject item; // 创建一个新的 QJsonObject 来存储数据
            qDebug() << "----------------------------------";

            // 检查对象中是否包含所有需要的键
            bool containsAllKeys = std::all_of(keys.begin(), keys.end(), [&obj](const QString &key) {
                return obj.contains(key);
            });

            if (containsAllKeys) {
                for (const QString &key : keys) {
                    QVariant varValue = obj[key].toVariant(); // 获取 QVariant
                    item[key] = QJsonValue::fromVariant(varValue); // 将 QVariant 转换为 QJsonValue 并存储
                    qDebug() << key << ":" << varValue; // 打印每个键的值
                }

                // 使用 QSet 检查键的集合，忽略顺序
                QSet<QString> keySet = QSet<QString>::fromList(keys);
                if (keySet.contains("UserID") && keySet.contains("Username") &&
                        keySet.contains("Password") && keySet.contains("Role") &&
                        keySet.contains("Name") && keySet.contains("Gender") &&
                        keySet.contains("Age") && keySet.contains("ContactNumber") &&
                        keySet.contains("Email")) {
                    this->usersData.append(item); // 存储用户数据
                }else if (keySet.contains("DoctorID") && keySet.contains("Name") &&
                          keySet.contains("ContactNumber") && keySet.contains("Specialization") &&
                          keySet.contains("Experience") && keySet.contains("Department") &&
                          keySet.contains("Title") && keySet.contains("Introduction") &&
                          keySet.contains("AvatarPath")&& keySet.contains("Username") &&
                          keySet.contains("Password") && keySet.contains("Role")) {
                     this->doctorsData.append(item); // 存储医生数据
                } else if (keySet.contains("PatientID") && keySet.contains("MedicalHistory") &&
                           keySet.contains("Allergies")) {
                    patientsData.append(item); // 存储患者数据
                } else if (keySet.contains("RecordID") && keySet.contains("PatientID") &&
                           keySet.contains("DoctorID") && keySet.contains("Diagnosis") &&
                           keySet.contains("Treatment") && keySet.contains("Date")) {
                    medicalRecordsData.append(item); // 存储病历数据
                } else if (keySet.contains("AppointmentID") && keySet.contains("AppointmentDate") &&
                           keySet.contains("Status") && keySet.contains("DoctorID") &&
                           keySet.contains("DoctorName") && keySet.contains("Department")){
                    appointmentsData.append(item);
                } else if (keySet.contains("AppointmentID") && keySet.contains("PatientID") &&
                           keySet.contains("DoctorID") && keySet.contains("AppointmentDate") &&
                           keySet.contains("Status")&& keySet.contains("PatientName") ) {
                    appointmentsData.append(item); // 存储预约数据
                } else if (keySet.contains("AdviceID") && keySet.contains("PatientID") &&
                           keySet.contains("DoctorID") && keySet.contains("Advice") &&
                           keySet.contains("Date")) {
                    medicalAdviceData.append(item); // 存储医疗建议数据
                } else if (keySet.contains("PrescriptionID") && keySet.contains("PatientID") &&
                           keySet.contains("DoctorID") && keySet.contains("Medication") &&
                           keySet.contains("Dosage") && keySet.contains("Date")) {
                    prescriptionsData.append(item); // 存储处方数据
                } else if (keySet.contains("MessageID") && keySet.contains("PatientID") &&
                           keySet.contains("DoctorID") && keySet.contains("Message") &&
                           keySet.contains("Date")) {
                    communicationData.append(item); // 存储沟通数据
                } else if (keySet.contains("AssessmentID") && keySet.contains("PatientID") &&
                           keySet.contains("Assessment") && keySet.contains("Date")) {
                    healthAssessmentsData.append(item); // 存储健康评估数据
                }else if (keySet.contains("DepartmentID") && keySet.contains("DepartmentName") &&
                          keySet.contains("Description")) {
                    departmentsData.append(item); // 存储部门数据
                }

                qDebug() << "----------------------------------";
            }
        }
    }
    qDebug() << "==================================";
}

// 获取存储数据的公共方法
QList<QJsonObject> ClientTcp::getUsersData() const {
    return usersData; // 返回用户数据
}

QList<QJsonObject> ClientTcp::getDepartments() const {
    return departmentsData;
}

QList<QJsonObject> ClientTcp::getDoctorsData() const {
    return doctorsData; // 返回医生数据
}

QList<QJsonObject> ClientTcp::getPatientsData() const {
    return patientsData; // 返回患者数据
}

QList<QJsonObject> ClientTcp::getMedicalRecordsData() const {
    return medicalRecordsData; // 返回病历数据
}

QList<QJsonObject> ClientTcp::getAppointmentsData() const {
    return appointmentsData; // 返回预约数据
}

QList<QJsonObject> ClientTcp::getMedicalAdviceData() const {
    return medicalAdviceData; // 返回医疗建议数据
}

QList<QJsonObject> ClientTcp::getPrescriptionsData() const {
    return prescriptionsData; // 返回处方数据
}

QList<QJsonObject> ClientTcp::getCommunicationData() const {
    return communicationData; // 返回沟通数据
}

QList<QJsonObject> ClientTcp::getHealthAssessmentsData() const {
    return healthAssessmentsData; // 返回健康评估数据
}

bool ClientTcp::getFlag() const {
    return flag;
}
